home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Source Code / Textures SDK / qlumpy / quakegrb.c < prev   
C/C++ Source or Header  |  1998-12-02  |  17KB  |  842 lines

  1. /***
  2. *
  3. *    Copyright (c) 1998, Valve LLC. All rights reserved.
  4. *    
  5. *    This product contains software technology licensed from Id 
  6. *    Software, Inc. ("Id Technology").  Id Technology (c) 1996 Id Software, Inc. 
  7. *    All Rights Reserved.
  8. *
  9. ****/
  10.  
  11. #include "qlumpy.h"
  12. #include "math.h"
  13.  
  14. #pragma warning (disable : 4244)
  15.  
  16. typedef struct
  17. {
  18.     short    ofs, length;
  19. } row_t;
  20.  
  21. typedef struct
  22. {
  23.     int        width, height;
  24.     int        widthbits, heightbits;
  25.     unsigned char    data[4];
  26. } qtex_t;
  27.  
  28. typedef struct
  29. {
  30.     int            width, height;
  31.     byte        data[4];            // variably sized
  32. } qpic_t;
  33.  
  34.  
  35. // Font stuff
  36.  
  37. #define NUM_GLYPHS 256
  38. const unsigned kFontMarker = 254;
  39.  
  40. typedef struct
  41. {
  42.     short startoffset;
  43.     short charwidth;
  44. } charinfo;
  45.  
  46. typedef struct
  47. {
  48.     int         width, height;
  49.     int            rowcount;
  50.     int            rowheight;
  51.     charinfo    fontinfo[ NUM_GLYPHS ];
  52.     byte         data[4];
  53. } qfont_t;
  54.  
  55.  
  56. extern qboolean        fTransparent255;
  57.  
  58.  
  59. #define SCRN(x,y)       (*(byteimage+(y)*byteimagewidth+x))
  60.  
  61. void GrabPalette16( void );
  62.  
  63. extern qboolean do16bit;
  64.  
  65. /*
  66. ==============
  67. GrabRaw
  68.  
  69. filename RAW x y width height
  70. ==============
  71. */
  72. void GrabRaw (void)
  73. {
  74.     int             x,y,xl,yl,xh,yh,w,h;
  75.     byte            *screen_p;
  76.     int             linedelta;
  77.  
  78.     GetToken (false);
  79.     xl = atoi (token);
  80.     GetToken (false);
  81.     yl = atoi (token);
  82.     GetToken (false);
  83.     w = atoi (token);
  84.     GetToken (false);
  85.     h = atoi (token);
  86.  
  87.     if (xl == -1)
  88.     {
  89.         xl = yl = 0;
  90.         w = byteimagewidth;
  91.         h = byteimageheight;
  92.     }
  93.  
  94.     xh = xl+w;
  95.     yh = yl+h;
  96.  
  97.     screen_p = byteimage + yl*byteimagewidth + xl;
  98.     linedelta = byteimagewidth - w;
  99.  
  100.     for (y=yl ; y<yh ; y++)
  101.     {
  102.         for (x=xl ; x<xh ; x++)
  103.         {
  104.             *lump_p++ = *screen_p;
  105.             *screen_p++ = 0;
  106.         }
  107.         screen_p += linedelta;
  108.     }
  109. }
  110.  
  111.  
  112.  
  113. /*
  114. ==============
  115. GrabPalette
  116.  
  117. filename PALETTE [startcolor endcolor]
  118. ==============
  119. */
  120. void GrabPalette (void)
  121. {
  122.     int start, end, length;
  123.  
  124.     if (TokenAvailable())
  125.     {
  126.         GetToken (false);
  127.         start = atoi (token);
  128.         GetToken (false);
  129.         end = atoi (token);
  130.     }
  131.     else
  132.     {
  133.         start = 0;
  134.         end = 255;
  135.     }
  136.  
  137.     length = 3*(end-start+1);
  138.     memcpy (lump_p, lbmpalette+start*3, length);
  139.     lump_p += length;
  140. }
  141.  
  142.  
  143. /*
  144. ==============
  145. GrabPic
  146.  
  147. filename qpic x y width height
  148. ==============
  149. */
  150. void GrabPic (void)
  151. {
  152.     int             x,y,xl,yl,xh,yh;
  153.     int             width;
  154.     qpic_t             *header;
  155.  
  156.     GetToken (false);
  157.     xl = atoi (token);
  158.     GetToken (false);
  159.     yl = atoi (token);
  160.     GetToken (false);
  161.     xh = xl+atoi (token);
  162.     GetToken (false);
  163.     yh = yl+atoi (token);
  164.  
  165.     if (xl == -1)
  166.     {
  167.         xl = yl = 0;
  168.         xh = byteimagewidth;
  169.         yh = byteimageheight;
  170.     }
  171.  
  172.     if (xh<xl || yh<yl || xl < 0 || yl<0) // || xh>319 || yh>239)
  173.         Error ("GrabPic: Bad size: %i, %i, %i, %i",xl,yl,xh,yh);
  174.  
  175.     //
  176.     // fill in header
  177.     //
  178.     header = (qpic_t *)lump_p;
  179.     width = xh-xl;
  180.     header->width = LittleLong(width);
  181.     header->height = LittleLong(yh-yl);
  182.  
  183.     //
  184.     // start grabbing posts
  185.     //
  186.     lump_p = (byte *)header->data;
  187.  
  188.     for (y=yl ; y< yh ; y++)
  189.         for (x=xl ; x<xh ; x++)
  190.             *lump_p++ = SCRN(x,y);
  191.  
  192.     // New for 16bpp display
  193.     if( do16bit )
  194.         GrabPalette16();
  195. }
  196.  
  197. /*
  198. =============================================================================
  199.  
  200. COLORMAP GRABBING
  201.  
  202. =============================================================================
  203. */
  204.  
  205. /*
  206. ===============
  207. BestColor
  208. ===============
  209. */
  210. byte BestColor (int r, int g, int b, int start, int stop)
  211. {
  212.     int    i;
  213.     int    dr, dg, db;
  214.     int    bestdistortion, distortion;
  215.     int    bestcolor;
  216.     byte    *pal;
  217.  
  218. //
  219. // let any color go to 0 as a last resort
  220. //
  221.     bestdistortion = ( (int)r*r + (int)g*g + (int)b*b )*2;
  222.     bestcolor = 0;
  223.  
  224.     pal = lbmpalette + start*3;
  225.     for (i=start ; i<= stop ; i++)
  226.     {
  227.         dr = r - (int)pal[0];
  228.         dg = g - (int)pal[1];
  229.         db = b - (int)pal[2];
  230.         pal += 3;
  231.         distortion = dr*dr + dg*dg + db*db;
  232.         if (distortion < bestdistortion)
  233.         {
  234.             if (!distortion)
  235.                 return i;        // perfect match
  236.  
  237.             bestdistortion = distortion;
  238.             bestcolor = i;
  239.         }
  240.     }
  241.  
  242.     return bestcolor;
  243. }
  244.  
  245.  
  246. /*
  247. ==============
  248. GrabColormap
  249.  
  250. filename COLORMAP levels fullbrights
  251. the first map is an identiy 0-255
  252. the final map is all black except for the fullbrights
  253. the remaining maps are evenly spread
  254. fullbright colors start at the top of the palette.
  255. ==============
  256. */
  257. void GrabColormap (void)
  258. {
  259.     int        levels, brights;
  260.     int        l, c;
  261.     float    frac, red, green, blue;
  262.         
  263.     GetToken (false);
  264.     levels = atoi (token);
  265.     GetToken (false);
  266.     brights = atoi (token);
  267.  
  268. // identity lump
  269.     for (l=0 ; l<256 ; l++)
  270.         *lump_p++ = l;
  271.  
  272. // shaded levels
  273.     for (l=1;l<levels;l++)
  274.     {
  275.         frac = 1.0 - (float)l/(levels-1);
  276.         for (c=0 ; c<256-brights ; c++)
  277.         {
  278.             red = lbmpalette[c*3];
  279.             green = lbmpalette[c*3+1];
  280.             blue = lbmpalette[c*3+2];
  281.  
  282.             red = (int)(red*frac+0.5);
  283.             green = (int)(green*frac+0.5);
  284.             blue = (int)(blue*frac+0.5);
  285.             
  286. //
  287. // note: 254 instead of 255 because 255 is the transparent color, and we
  288. // don't want anything remapping to that
  289. //
  290.             *lump_p++ = BestColor(red,green,blue, 0, 254);
  291.         }
  292.         for ( ; c<256 ; c++)
  293.             *lump_p++ = c;
  294.     }
  295.     
  296.     *lump_p++ = brights;
  297. }
  298.  
  299. /*
  300. ==============
  301. GrabColormap2
  302.  
  303. experimental -- not used by quake
  304.  
  305. filename COLORMAP2 range levels fullbrights
  306. fullbright colors start at the top of the palette.
  307. Range can be greater than 1 to allow overbright color tables.
  308.  
  309. the first map is all 0
  310. the last (levels-1) map is at range
  311. ==============
  312. */
  313. void GrabColormap2 (void)
  314. {
  315.     int        levels, brights;
  316.     int        l, c;
  317.     float    frac, red, green, blue;
  318.     float    range;
  319.     
  320.     GetToken (false);
  321.     range = atof (token);
  322.     GetToken (false);
  323.     levels = atoi (token);
  324.     GetToken (false);
  325.     brights = atoi (token);
  326.  
  327. // shaded levels
  328.     for (l=0;l<levels;l++)
  329.     {
  330.         frac = range - range*(float)l/(levels-1);
  331.         for (c=0 ; c<256-brights ; c++)
  332.         {
  333.             red = lbmpalette[c*3];
  334.             green = lbmpalette[c*3+1];
  335.             blue = lbmpalette[c*3+2];
  336.  
  337.             red = (int)(red*frac+0.5);
  338.             green = (int)(green*frac+0.5);
  339.             blue = (int)(blue*frac+0.5);
  340.             
  341. //
  342. // note: 254 instead of 255 because 255 is the transparent color, and we
  343. // don't want anything remapping to that
  344. //
  345.             *lump_p++ = BestColor(red,green,blue, 0, 254);
  346.         }
  347.  
  348.         // fullbrights allways stay the same
  349.         for ( ; c<256 ; c++)
  350.             *lump_p++ = c;
  351.     }
  352.     
  353.     *lump_p++ = brights;
  354. }
  355.  
  356. /*
  357. =============================================================================
  358.  
  359. MIPTEX GRABBING
  360.  
  361. =============================================================================
  362. */
  363.  
  364. typedef struct
  365. {
  366.     char        name[16];
  367.     unsigned    width, height;
  368.     unsigned    offsets[4];        // four mip maps stored
  369. } miptex_t;
  370.  
  371. byte    pixdata[256];
  372.  
  373. float     linearpalette[256][3];
  374. float     d_red, d_green, d_blue;
  375. int        colors_used;
  376. int        color_used[256];
  377. float    maxdistortion;
  378.  
  379. byte AddColor( float r, float g, float b )
  380. {
  381.     int i;
  382.     for (i = 0; i < 255; i++)
  383.     {
  384.         if (!color_used[i])
  385.         {
  386.             linearpalette[i][0] = r;
  387.             linearpalette[i][1] = g;
  388.             linearpalette[i][2] = b;
  389.             if (r < 0) r = 0.0;
  390.             if (r > 1.0) r = 1.0;
  391.             lbmpalette[i*3+0] = pow( r, 1.0 / 2.2) * 255;
  392.             if (g < 0) g = 0.0;
  393.             if (g > 1.0) g = 1.0;
  394.             lbmpalette[i*3+1] = pow( g, 1.0 / 2.2) * 255;
  395.             if (b < 0) b = 0.0;
  396.             if (b > 1.0) b = 1.0;
  397.             lbmpalette[i*3+2] = pow( b, 1.0 / 2.2) * 255;
  398.             color_used[i] = 1;
  399.             colors_used++;
  400.             return i;
  401.         }
  402.     }
  403.     return 0;
  404. }
  405.  
  406. /*
  407. =============
  408. AveragePixels
  409. =============
  410. */
  411. byte AveragePixels (int count)
  412. {
  413.     float   r,g,b;
  414.     int        i;
  415.     int        vis;
  416.     int        pix;
  417.     float     dr, dg, db;
  418.     float     bestdistortion, distortion;
  419.     int        bestcolor;
  420.     byte    *pal;
  421.     
  422.     vis = 0;
  423.     r = g = b = 0;
  424.  
  425.     for (i=0 ; i<count ; i++)
  426.     {
  427.         pix = pixdata[i];
  428.         r += linearpalette[pix][0];
  429.         g += linearpalette[pix][1];
  430.         b += linearpalette[pix][2];
  431.     }
  432.  
  433.     r /= count;
  434.     g /= count;
  435.     b /= count;
  436.  
  437.     r += d_red;
  438.     g += d_green;
  439.     b += d_blue;
  440.     
  441. //
  442. // find the best color
  443. //
  444. //    bestdistortion = r*r + g*g + b*b;
  445.     bestdistortion = 3.0;
  446.     bestcolor = -1;
  447.  
  448.     for ( i=0; i<255; i++)
  449.     {
  450.         if (color_used[i])
  451.         {
  452.             pix = i;    //pixdata[i];
  453.  
  454.             dr = r - linearpalette[i][0];
  455.             dg = g - linearpalette[i][1];
  456.             db = b - linearpalette[i][2];
  457.  
  458.             distortion = dr*dr + dg*dg + db*db;
  459.             if (distortion < bestdistortion)
  460.             {
  461.                 if (!distortion)
  462.                 {
  463.                     d_red = d_green = d_blue = 0;    // no distortion yet
  464.                     return pix;        // perfect match
  465.                 }
  466.  
  467.                 bestdistortion = distortion;
  468.                 bestcolor = pix;
  469.             }
  470.         }
  471.     }
  472.  
  473.  
  474.     if (bestdistortion > 0.001 && colors_used < 255)
  475.     {
  476.         // printf("%f %f %f\n", r, g, b );
  477.         bestcolor = AddColor( r, g, b );
  478.         d_red = d_green = d_blue = 0;
  479.         bestdistortion = 0;
  480.     }
  481.     else
  482.     {
  483.         // error diffusion
  484.         d_red = r - linearpalette[bestcolor][0];
  485.         d_green = g - linearpalette[bestcolor][1];
  486.         d_blue = b - linearpalette[bestcolor][2];
  487.     }
  488.  
  489.     if (bestdistortion > maxdistortion)
  490.         maxdistortion = bestdistortion;
  491.     return bestcolor;
  492. }
  493.  
  494.  
  495. /*
  496. ==============
  497. GrabMip
  498.  
  499. filename MIP x y width height
  500. must be multiples of sixteen
  501. ==============
  502. */
  503. void GrabMip (void)
  504. {
  505.     int             i,j,x,y,xl,yl,xh,yh,w,h;
  506.     byte            *screen_p, *source, testpixel;
  507.     int             linedelta;
  508.     miptex_t        *qtex;
  509.     int                miplevel, mipstep;
  510.     int                xx, yy, pix;
  511.     int                count;
  512.     
  513.     GetToken (false);
  514.     xl = atoi (token);
  515.     GetToken (false);
  516.     yl = atoi (token);
  517.     GetToken (false);
  518.     w = atoi (token);
  519.     GetToken (false);
  520.     h = atoi (token);
  521.  
  522.     if (xl == -1)
  523.     {
  524.         xl = yl = 0;
  525.         w = byteimagewidth;
  526.         h = byteimageheight;
  527.     }
  528.  
  529.     if ( (w & 15) || (h & 15) )
  530.         Error ("line %i: miptex sizes must be multiples of 16", scriptline);
  531.  
  532.     xh = xl+w;
  533.     yh = yl+h;
  534.  
  535.     qtex = (miptex_t *)lump_p;
  536.     qtex->width = LittleLong(w);
  537.     qtex->height = LittleLong(h);
  538.     strcpy (qtex->name, lumpname); 
  539.     
  540.     lump_p = (byte *)&qtex->offsets[4];
  541.     
  542.     screen_p = byteimage + yl*byteimagewidth + xl;
  543.     linedelta = byteimagewidth - w;
  544.  
  545.     source = lump_p;
  546.     qtex->offsets[0] = LittleLong(lump_p - (byte *)qtex);
  547.  
  548.     for (y=yl ; y<yh ; y++)
  549.     {
  550.         for (x=xl ; x<xh ; x++)
  551.         {
  552.             pix = *screen_p;
  553.             *screen_p++ = 0;
  554. //            if (pix == 255)
  555. //                pix = 0;
  556.             *lump_p++ = pix;
  557.         }
  558.         screen_p += linedelta;
  559.     }
  560.  
  561.     // calculate gamma corrected linear palette
  562.     for (i = 0; i < 256; i++)
  563.     {
  564.         for (j = 0; j < 3; j++)
  565.         {
  566.             float f;
  567.             f = lbmpalette[i*3+j] / 255.0;
  568.             linearpalette[i][j] = pow(f, 2.2 ); // assume textures are done at 2.2, we want to remap them at 1.0
  569.         }
  570.     }
  571.  
  572.     maxdistortion = 0;
  573.     if (!fTransparent255)
  574.     {
  575.         // figure out what palette entries are actually used
  576.         colors_used = 0;
  577.         for (i = 0; i < 256; i++)
  578.             color_used[i] = 0;
  579.  
  580.         for (x = 0; x < w; x++)
  581.         {
  582.             for (y = 0; y < h; y++)
  583.             {
  584.                 if (!color_used[source[ y*w + x]])
  585.                 {
  586.                     color_used[source[ y*w + x]] = 1;
  587.                     colors_used++;
  588.                 }
  589.             }
  590.         }
  591.     }
  592.     else
  593.     {
  594.         // assume palette full if it's a transparent texture
  595.         colors_used = 256;
  596.         for (i = 0; i < 256; i++)
  597.             color_used[i] = 1;
  598.     }
  599.     // printf("colors_used %d : ", colors_used );
  600.  
  601.  
  602.     //
  603.     // subsample for greater mip levels
  604.     //
  605.  
  606.     for (miplevel = 1 ; miplevel<4 ; miplevel++)
  607.     {
  608.         int pixTest;
  609.         d_red = d_green = d_blue = 0;    // no distortion yet
  610.         qtex->offsets[miplevel] = LittleLong(lump_p - (byte *)qtex);
  611.         
  612.         mipstep = 1<<miplevel;
  613.         pixTest = (int)( (float)(mipstep * mipstep) * 0.4 );    // 40% of pixels
  614.  
  615.         for (y=0 ; y<h ; y+=mipstep)
  616.         {
  617.             for (x = 0 ; x<w ; x+= mipstep)
  618.             {
  619.                 count = 0;
  620.                 for (yy=0 ; yy<mipstep ; yy++)
  621.                     for (xx=0 ; xx<mipstep ; xx++)
  622.                     {
  623.                         testpixel = source[ (y+yy)*w + x + xx ];
  624.                         
  625.                         // If 255 is not transparent, or this isn't a transparent pixel, add it in to the image filter
  626.                         if ( !fTransparent255 || testpixel != 255 ) {
  627.                             pixdata[count] = testpixel;
  628.                             count++;
  629.                         }
  630.                     }
  631.                 if ( count <= pixTest )    // Solid pixels account for < 40% of this pixel, make it transparent
  632.                 {
  633.                     *lump_p++ = 255;
  634.                 }
  635.                 else
  636.                 {
  637.                     *lump_p++ = AveragePixels (count);
  638.                 }
  639.             }    
  640.         }
  641.     }
  642.  
  643.     // printf(" %d %f\n", colors_used, maxdistortion );
  644.  
  645.     if( do16bit )
  646.         GrabPalette16();
  647. }
  648.  
  649.  
  650. /*
  651. =============================================================================
  652.  
  653. PALETTE GRABBING
  654.  
  655. =============================================================================
  656. */
  657.  
  658.  
  659. void GrabPalette16( void )
  660. {
  661.     int i;
  662.  
  663.     // Write out palette in 16bit mode
  664.     *(unsigned short *) lump_p = 256;    // palette size
  665.     lump_p += sizeof(short);
  666.  
  667.     memcpy( lump_p, lbmpalette, 768 );
  668.     lump_p += 768;
  669. }
  670.  
  671.  
  672.  
  673. /*
  674. =============================================================================
  675.  
  676. FONT GRABBING
  677.  
  678. =============================================================================
  679. */
  680.  
  681.  
  682. /*
  683. ==============
  684. GrabFont
  685.  
  686. font x y width height startglyph
  687. ==============
  688. */
  689. void GrabFont( void )
  690. {
  691.     int        x, y, y2, xl, x2, yl, xh, yh, i, j;
  692.     int        index, offset;
  693.     int        width;
  694.     int        iCurX;    // current x in destination
  695.     int        iMaxX;  // max x in destination
  696.     
  697.     byte    *pbuf, *pCur;
  698.     qfont_t             *header;
  699.  
  700.  
  701.     iMaxX = 255;
  702.     iCurX = 0;
  703.  
  704.     // Set up header
  705.     header = (qfont_t *)lump_p;
  706.     memset( header, 0, sizeof(qfont_t) );
  707.  
  708.     GetToken( false );
  709.     header->width = header->rowheight = atoi( token );  //mwh why does width equal rowheight? 
  710.     header->height = 1;
  711.     lump_p = (byte *)header->data;
  712.     pCur = (byte *)lump_p;
  713.     memset( lump_p, 0xFF, 256 * 160);
  714.  
  715.     GetToken( false );
  716.     index = atoi( token );
  717.  
  718.     while( index != -1 )
  719.     {
  720.         // Get/Process source bitmap coordinates
  721.         GetToken (false);
  722.         xl = atoi (token);
  723.         GetToken (false);
  724.         yl = atoi (token);
  725.         GetToken (false);
  726.         xh = xl-1+atoi (token);
  727.         GetToken (false);
  728.         yh = atoi (token) - 1;
  729.         if (xl == -1)
  730.         {
  731.             xl = yl = 0;
  732.             xh = byteimagewidth;
  733.             yh = byteimageheight;
  734.         }
  735.  
  736.         if( xh<xl || yh<yl || xl < 0 || yl<0 )
  737.             Error( "GrabFont line %1: Bad size: %i, %i, %i, %i", scriptline, xl, yl, xh, yh );
  738.  
  739.         //
  740.         // Fill in font information
  741.         // Create a bitmap that is up to 256 wide and as tall as we need to accomadate the font.
  742.         // We limit the bitmap to 256 because some 3d boards have problems with textures bigger 
  743.         // than that. 
  744.         //
  745.         for( y=yl; y<yh; y+=header->rowheight+1 )
  746.         {
  747.             // Make sure we're at a marker
  748.             if( y != yl )
  749.             {
  750.                 for( y2=y-header->rowheight; y2<yh; y2++ )
  751.                     if( kFontMarker == (unsigned) SCRN(xl,y2) )
  752.                         break;
  753.  
  754.                 if( y2 == yh )
  755.                     break;
  756.                 else if( y2 != y )
  757.                     Error( "GrabFont line %d: rowheight doesn't seem to match bitmap (%d, %d)\n", scriptline, y, y2 );
  758.             }
  759.  
  760.             for( x=xl; x<xh; )
  761.             {
  762.                 // find next marker
  763.                 for( x2=x+1; x2<xh; x2++ )
  764.                     if( kFontMarker == (unsigned) SCRN(x2,y) )
  765.                         break;
  766.  
  767.                 // check for end of row
  768.                 if( x2 == xh )
  769.                     break;
  770.  
  771.                 // Set up glyph information
  772.                 if( index >= NUM_GLYPHS )
  773.                 {
  774.                     printf( "GrabFont: Glyph out of range\n" );
  775.                     goto getout;
  776.                 }
  777.         
  778.                 // Fill in glyph info
  779.                 header->fontinfo[ index ].charwidth = x2 - x - 1;
  780.                 
  781.                 // update header                
  782.  
  783.                 // output glyph data
  784.                 iCurX += header->fontinfo[index].charwidth;
  785.                 
  786.                 // Will this glyph fit on this row?
  787.                 if (iCurX >= iMaxX)
  788.                 {    
  789.                     // Nope -- move to next row
  790.                     pCur = (byte *)lump_p + 256 * header->rowheight * header->height;
  791.                     header->height++;
  792.                     iCurX = header->fontinfo[index].charwidth;
  793.                 } 
  794.             
  795.                 // copy over the glyph bytes
  796.                 pbuf = pCur;
  797.                 header->fontinfo[ index ].startoffset = pCur - (byte *) header->data;
  798.                 
  799.  
  800.                 for(j = 1; j <= header->rowheight; j++)
  801.                 {
  802.                     byte *psrc = byteimage + (y + j) * byteimagewidth + (x + 1);
  803.  
  804.                     for(i = x + 1; i < x2; i++)
  805.                         *pbuf++ = *psrc++;
  806.  
  807.                     pbuf = pCur + j * 256;
  808.                 }
  809.                 
  810.                 // move the lump pointer to point at the next possible glyph
  811.                 pCur += header->fontinfo[index].charwidth;
  812.                 x = x2;
  813.                 index++;
  814.             }
  815.         }
  816.  
  817.         // Get next ASCII index
  818. getout:
  819.         GetToken (false);
  820.         index = atoi (token);
  821.     }
  822.  
  823.     // advance the lump pointer so that the last row is saved.
  824.     lump_p += (256 * header->rowheight) * header->height;
  825.     
  826.     // JAY: Round up to the next power of 2 for GL
  827.     offset = header->height * header->rowheight;
  828.  
  829.     y = (offset>128)?256:(offset>64)?128:(offset>32)?64:(offset>16)?32:16;
  830.     if ( offset != y )
  831.     {
  832.         printf("Rounding font from 256x%d to 256x%d\n", offset, y );
  833.         lump_p += (256 * (y - offset));
  834.     }
  835.     header->rowcount = header->height;
  836.     header->height = y;
  837.  
  838.     if( do16bit )
  839.         GrabPalette16();
  840. }
  841.  
  842.